package eScrum.pages;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.spring.injection.annot.SpringBean;
import eScrum.components.MWindow;
import eScrum.entities.User;
import eScrum.entities.UserRole;
import eScrum.entities.UserSearchCriteria;
import eScrum.entities.UserStatus;
import eScrum.panels.CreateUserPopUpPanel;
import eScrum.panels.InfoDialog;
import eScrum.panels.MessageDialog;
import eScrum.services.UserService;

@AuthorizeInstantiation("ADMIN")
public class AdminDashboard extends TeleBasePage {

	private static final long serialVersionUID = 6950606065332454560L;
	
	
	private WebMarkupContainer userListContainer;
	private DataView<User> dataView;
	private MWindow userWindow = null;

	@SpringBean
	private UserService userService;

	private UserSearchCriteria userSearchCriteria = new UserSearchCriteria();

	private WebMarkupContainer footer;
	protected long userId = -1;

	FeedbackPanel feedback = new FeedbackPanel("feedback");

	public AdminDashboard(PageParameters params) {
		super(params);

		addModalWindow();
		add(feedback);
		feedback.setOutputMarkupId(true);
		addUserListContainer();
		addSearchForm();
	}

	private void addModalWindow() {
		userWindow = new MWindow("modalUserPage");
		userWindow.setTitle("Create/edit user");
		userWindow.setInitialHeight(300);
		userWindow.setInitialWidth(780);
		userWindow.setResizable(false);
		add(userWindow);
	}

	@SuppressWarnings("serial")
	private void addUserListContainer() {

		feedback.setOutputMarkupId(true);
		userListContainer = new WebMarkupContainer("userListContainer");
		userListContainer.setOutputMarkupId(true);

		dataView = new DataView<User>("userslist", new UserDataProvider(userSearchCriteria, userService)) {

			protected void populateItem(final Item<User> item) {
				item.setOutputMarkupId(true);
				final User user = item.getModelObject();

				item.add(new Label("name", user.getFirstName() + " " + user.getLastName()));
				item.add(new Label("role", (user.getRole() != null ? user.getRole().toString() : "")));
				item.add(new Label("username", user.getUsername()));

				item.add(new AjaxLink<Object>("delete") {

					@Override
					public void onClick(AjaxRequestTarget target) {
						userWindow.setTitle(getString("deleteUser"));
						userWindow.setInitialHeight(150);
						userWindow.setInitialWidth(260);
						if (user.getRole() != null) {
							if (user.getRole().toString().equals("ADMIN")) {
								userWindow.setContent(new InfoDialog(userWindow.getContentId(), getString("cannotDeleteAdmin")));
							} else
								userWindow.setContent(new MessageDialog(userWindow.getContentId(), getString("deleteUser") + " "
										+ user.getFirstName() + " " + user.getLastName() + "?") {

									@Override
									public void onOk(AjaxRequestTarget target) {
										try {
											super.onOk(target);
											target.add(feedback);
											doDeleteUser(user);
											target.add(userListContainer);
											target.add(footer);
											target.add(AdminDashboard.this);

										} catch (Exception e) {
											reportUnexpectedException(e);
										}

									}
								});

							userWindow.show(target);
							target.add(userListContainer);
						}

					}
				});

				item.add(new AjaxLink<Object>("edit") {

					@Override
					public void onClick(AjaxRequestTarget target) {
						userId = user.getId();
						/*userWindow.setTitle(getString("editUser"));*/
						userWindow.setContent(new CreateUserPopUpPanel(userWindow.getContentId(), userId) {

							@Override
							public void refreshData(AjaxRequestTarget target) {
								super.refreshData(target);
								target.add(userListContainer);
								target.add(footer);
							}

						});
						userWindow.setInitialHeight(300);
						userWindow.setInitialWidth(780);
						userWindow.show(target);
					}
				});

				WebMarkupContainer personIcon = new WebMarkupContainer("personIcon");
				item.add(personIcon);
				if (user.getStatus() == UserStatus.ACTIVE) {
					personIcon.add(new AttributeModifier("class", "person_icon"));
				} else {
					personIcon.add(new AttributeModifier("class", "person_icon_light"));
				}

				WebMarkupContainer color = new WebMarkupContainer("color");
				item.add(color);

				color.add(AttributeModifier.replace("class", new AbstractReadOnlyModel<String>() {

					@Override
					public String getObject() {
						String ret = "colorc ";
						if (UserRole.DEVELOPER.equals(user.getRole()))
							ret += "green";
						else if (UserRole.POWERUSER.equals(user.getRole()))
							ret += "blue";
						else if (UserRole.ClASSICUSER.equals(user.getRole()))
							ret += "pink";
						else if (UserRole.ADMIN.equals(user.getRole()))
							ret += "yellow";
						else
							ret += "brown";
						return ret;
					}
				}));

				item.add(AttributeModifier.replace("class", new AbstractReadOnlyModel<String>() {

					@Override
					public String getObject() {
						String ret = "tline ";
						ret += (item.getIndex() % 2 == 1) ? "" : " alt";
						if (user.getStatus() == UserStatus.ACTIVE)
							ret += " active";
						else
							ret += " suspended";
						return ret;
					}
				}));

			}

		};
		dataView.setOutputMarkupId(true);
		dataView.setItemsPerPage(8);
		footer = new WebMarkupContainer("patients_footer") {

			@Override
			public boolean isVisible() {
				return dataView.getPageCount() > 1;

			}
		};

		footer.setOutputMarkupId(true);

		footer.add(new PagingNavigator("navigator", dataView));

		add(new AjaxLink<Object>("addUser") {

			@Override
			public void onClick(AjaxRequestTarget target) {
				userId = -1;
				userWindow.setTitle(getString("createUser"));
				userWindow.setInitialHeight(300);
				userWindow.setInitialWidth(780);
				userWindow.setContent(new CreateUserPopUpPanel(userWindow.getContentId(), userId) {

					@Override
					public void refreshData(AjaxRequestTarget target) {
						super.refreshData(target);
						target.add(userListContainer);
						target.add(footer);
						target.add(AdminDashboard.this);
					}

				});
				userWindow.show(target);
			}
		});
		
		userListContainer.add(dataView);
		add(userListContainer);
		add(footer);

	}

	@SuppressWarnings("serial")
	private void addSearchForm() {

		final CompoundPropertyModel<UserSearchCriteria> userModel = new CompoundPropertyModel<UserSearchCriteria>(userSearchCriteria);

		Form<UserSearchCriteria> searchForm = new Form<UserSearchCriteria>("searchForm", userModel);

		AjaxLink<Boolean> chk0 = new AjaxLink<Boolean>("developersFilter", userModel.<Boolean> bind("isiDeveloper")) {

			@Override
			public void onClick(AjaxRequestTarget target) {

				UserSearchCriteria crt = userModel.getObject();
				crt.setiDeveloper(!crt.isiDeveloper());

				if (crt.isiDeveloper()) {
					this.add(new AttributeModifier("class", "cnf selected"));
				} else {
					this.add(new AttributeModifier("class", "cnf"));
				}

				target.add(this);
				target.add(this.getParent().getParent());
				refreshList(target, crt);
			}
		};
		AjaxLink<Boolean> chk1 = new AjaxLink<Boolean>("powerusersFilter", userModel.<Boolean> bind("isPowerUser")) {

			@Override
			public void onClick(AjaxRequestTarget target) {

				UserSearchCriteria crt = userModel.getObject();
				crt.setPowerUser((!crt.isPowerUser()));

				if (crt.isPowerUser()) {
					this.add(new AttributeModifier("class", "nf selected"));
				} else {
					this.add(new AttributeModifier("class", "nf"));
				}

				target.add(this);
				target.add(this.getParent().getParent());
				refreshList(target, userModel.getObject());
			}
		};
		AjaxLink<Boolean> chk2 = new AjaxLink<Boolean>("classicusersFilter", userModel.<Boolean> bind("isClassicUser")) {

			@Override
			public void onClick(AjaxRequestTarget target) {

				UserSearchCriteria crt = userModel.getObject();
				crt.setClassicUser(!crt.isClassicUser());

				if (crt.isClassicUser()) {
					this.add(new AttributeModifier("class", "df selected"));
				} else {
					this.add(new AttributeModifier("class", "df"));
				}

				target.add(this);
				target.add(this.getParent().getParent());
				refreshList(target, userModel.getObject());
			}
		};

		AjaxLink<Boolean> chk3 = new AjaxLink<Boolean>("suspendedUsers", userModel.<Boolean> bind("isSuspended")) {

			@Override
			public void onClick(AjaxRequestTarget target) {

				UserSearchCriteria crt = userModel.getObject();
				crt.setSuspended(!crt.isSuspended());

				if (crt.isSuspended()) {
					this.add(new AttributeModifier("class", "suf selected"));
				} else {
					this.add(new AttributeModifier("class", "suf"));
				}

				target.add(this);
				target.add(this.getParent().getParent());
				refreshList(target, userModel.getObject());
			}
		};

		AjaxLink<Boolean> chk4 = new AjaxLink<Boolean>("activeUsers", userModel.<Boolean> bind("isActive")) {

			@Override
			public void onClick(AjaxRequestTarget target) {

				UserSearchCriteria crt = userModel.getObject();
				crt.setActive(!crt.isActive());

				if (crt.isActive()) {
					this.add(new AttributeModifier("class", "auf selected"));
				} else {
					this.add(new AttributeModifier("class", "auf"));
				}

				target.add(this);
				target.add(this.getParent().getParent());
				refreshList(target, userModel.getObject());
			}
		};

		searchForm.add(chk0);
		searchForm.add(chk1);
		searchForm.add(chk2);
		searchForm.add(chk3);
		searchForm.add(chk4);

		chk0.setOutputMarkupId(true);
		chk1.setOutputMarkupId(true);
		chk2.setOutputMarkupId(true);
		chk3.setOutputMarkupId(true);
		chk4.setOutputMarkupId(true);
		add(searchForm);
	}

	private void refreshList(AjaxRequestTarget target, UserSearchCriteria crt) {
		target.add(userListContainer);
	}

	private void doDeleteUser(final User user) {
		userService.deleteUser(String.valueOf(user.getId()));
	}

}
